//ChannelMGR.cpp
//**************************************************************
//* ChannelMGR  <<Control>> By Duk-ho
//* Revision by Taek han, Go (FreeMan)
//**************************************************************
#include <mysql++.h>
#include <datetime.h>
#include <row.h>

using namespace mysqlpp;

#include <string>
#include "Date.h"
#include "Channel.h"
#include "ChannelMGR.h"

using namespace std;
using namespace userDate;


//Find - CompareByLink
int CompareByLink(void* one, void* other)
{
	int ret;
//	printf("%s\n", (*((string*)other)).c_str() );
//	printf("%s\n", (((Channel*)one)->GetLink()).c_str() );
	
	if( ((Channel*)one)->GetLink() == *((string*)other) )
    {
		ret = 0;
	}

	return ret;
}


//////////////////////////////////////////////////////////////////////////////////////////////
//	Constructor & Destructor																//
//////////////////////////////////////////////////////////////////////////////////////////////

//Constructor
ChannelMGR::ChannelMGR() : channels()
{
        this-> count = 0;
}


//Copy Constructor
ChannelMGR::ChannelMGR(const ChannelMGR& source) : channels(source.channels)
{
        this->count = source.count;
}


//Destructor
ChannelMGR::~ChannelMGR()
{
}

//////////////////////////////////////////////////////////////////////////////////////////
//	Operators																			//
//////////////////////////////////////////////////////////////////////////////////////////

// = Operator
ChannelMGR& ChannelMGR::operator = (const ChannelMGR& source)
{
        this->channels = source.channels;
        this->count = source.count;

        return (*this);
}

// [] Operator
Channel& ChannelMGR::operator [] (int index)
{
        return (this->channels)[index];
}

// + Operator
Channel* ChannelMGR::operator + (int index)
{
	int i = 0;

	Node<Channel>* returnIndex = 0;

	Channel* returnValue = 0;

	while( i < index )
	{
		returnIndex = (this->channels).Next();

		returnValue = &(this->channels.GetObject( returnIndex ) );
		
		i++;
	}

	return returnValue;
}


//////////////////////////////////////////////////////////////////////////////////////////////
//	Member Functions																		//
//////////////////////////////////////////////////////////////////////////////////////////////

//Record
Channel* ChannelMGR::Record( string link, string title, string description, userDate::Date publishDate )
{
	//Create Channel Type Object
	Channel object( link, title, description, publishDate );

	//Declaration Channel Type Variable
	Channel* channel = 0;
	
	//Declaration Node Type Variable
    Node<Channel>* index = 0;

    index = this->channels.AppendFromTail( object );

	
    if( index != 0 )
    {
		//Get Channel Address
        channel = &( this->channels.GetObject( index ) );

		//Increase Channel Count
		(this->count)++;

		//Open the Database
		Connection con( "rss", "localhost", "root", "dreams" );

		try {
			//Declaration Query Variable
			Query query = con.query();

			//이전 쿼리
			//Set Query
			/*
			query << "call InsertChannel( \""
				  << link.c_str() << "\", \""
				  << title.c_str() << "\", \""
				  << description.c_str() << "\", \""
				  << publishDate.GetYear() << "-" << publishDate.GetMonth() << "-" << publishDate.GetDay() << " " 
				  << publishDate.GetHour() << ":" << publishDate.GetMin() << ":" << publishDate.GetSecond() << "\");";
			*/
			//변경된 쿼리
			//1999-01-01 00:00:00
			char dateChar[20] = "";
			sprintf(dateChar, "%d-%d-%d %d:%d:%d", publishDate.GetYear(), publishDate.GetMonth(), publishDate.GetDay(),
												   publishDate.GetHour(), publishDate.GetMin(), publishDate.GetSecond() );
			query << "insert into Channel values (    \""
				  << title.c_str() 		 << "\", \""
				  << description.c_str() << "\", \""
				  << dateChar 			 << "\", \""
				  << link.c_str()		 << "\");" ;

			query.parse();
		
			//Execute Query
			query.execute();
		}
		catch( const BadQuery& er )
		{
			cerr << "Query error : " << er.what() << endl;
		}
    }

		cout << ">> Channel Success. [" <<  channel->GetTitle() << "]" << endl;

	//Return the return value
	return channel;
}


//Find
Channel* ChannelMGR::Find( string link )
{
	Channel* returnValue = 0;
	
	Node<Channel>* index = 0;
		
		index = this->channels.LinearSearchUnique( &link, CompareByLink );

	if( index != 0 )
		{
			returnValue = &( this->channels.GetObject( index ) );
		}

	return returnValue;
}


//RecordChannelImage
void RecordChannelImage( string imageURL, string title, int width, int height, string description, string channelLink )
{
	//Open the Database
	Connection con( "rss", "localhost", "root", "dreams" );

	//Declaration Query Variable
	Query query = con.query();

	try {
		//이전 쿼리
		/*
		//Set Query
		query << "call InsertChannelImage( \"" 
			  << const_cast<char*>( imageURL.c_str() ) << "\", \""
			  << const_cast<char*>( title.c_str() ) << "\", \""
			  << width << "\", \""
			  << height << "\", \""
			  << const_cast<char*>( description.c_str() ) << "\", \""
			  << const_cast<char*>( channelLink.c_str() ) << "\" )";
		*/
		//변경된 쿼리

		query << "insert into ChannelImage values( \""
			<< const_cast<char*>( title.c_str() ) << "\", \""
			<< width << "\", \""
			<< height << "\", \""
			<< const_cast<char*>( channelLink.c_str() ) << "\", \""
			<< const_cast<char*>( imageURL.c_str() ) << "\", \""
			<< const_cast<char*>( description.c_str() ) << "\" );";

		
		query.parse();

		//Execure Query
		query.execute();
	}
	catch( const BadQuery& er )
	{
		cerr << "Query error : " << er.what() << endl;
	}
}



//////////////////////////////////////////////////////////////////////////////////////////
//                                                                                      //
//  Database Load : Get Data from the Database (Channel Table)  		                //
//  Creator : Taek han, Go(FreeMan)                                                     //
//  Revision Date : 2007/01/13		                                                    //
//  Perpose : Load the date from the Datebase										    //
//  Information : Datetime Datatye is imperfect.(Don't know the use)                    //
//                                                                                      //
//////////////////////////////////////////////////////////////////////////////////////////

void ChannelMGR::LoadDB()
{
    //Open the Database( DB Name : rss, Host Name : localhost, ID : root, Password : dreams )
    Connection con( "rss", "localhost", "root", "dreams" );

    //Declaration Query Variable
    Query query = con.query();

    //Set Query
    query << "select Channel.channelLink, Channel.title, Channel.description, Channel.pubDate from Channel;";

    //Store the ResultSet in Result Type Variable
    Result res = query.store();

	int count = 0;

	count = res.num_rows();

	if( count > 0 )
	{
	    //Save the row data in Row Type Variable
	    Row row = res.fetch_row();
	
	    Row::size_type i;
	
		//Declaration Integer Variable for Month
		int month = 0;
	
		this->count = 0;
	
	    try {   
   	     //Loop for Save the data in Tag Object
	     //Refer to Sample Code of MySQL++
	        for( i = 0; row = res.at(i); ++i )
	        {
				//Get month from DateTime Struct
				month = ( DateTime( string( row.raw_data(3) ) ) ).month;
			
	            //Declaration Tag Type Variable
	            Channel object( string( row.raw_data(0) ),
								string( row.raw_data(1) ),
								string( row.raw_data(2) ),
								userDate::Date
									(
									static_cast< ChannelMGR::UShort >( ( DateTime( string( row.raw_data(3) ) ) ).year ),
									static_cast< userDate::Date::Month >( month ),
									static_cast< ChannelMGR::UShort >( ( DateTime( string( row.raw_data(3) ) ) ).day ),
									static_cast< ChannelMGR::UShort >( ( DateTime( string( row.raw_data(3) ) ) ).hour ),
									static_cast< ChannelMGR::UShort >( ( DateTime( string( row.raw_data(3) ) ) ).minute ),
									static_cast< ChannelMGR::UShort >( ( DateTime( string( row.raw_data(3) ) ) ).second )	
								)
							  );

				this->channels.AppendFromTail( object );

				(this->count)++;
			}
		}
		catch( const BadQuery& er )
		{
			cerr << "Query error : " << er.what() << endl;
		}		
		catch( const EndOfResults& end )
		{
		}
	}
}


/*
int main()
{
	return 0;
}
*/
